
#import "ConvertObject.h"
#import <appkit/Form.h>

#define EXTENSION_LIST "c", "h", "m", "cc", "e"
@implementation ConvertObject

- convertMethod:sender
{
   
typedef	int	Token ;
#define	STOP_INPUT	0
#define	NEWLINE	1
#define START_COMMENT	2
#define END_COMMENT	3
#define	MISC_CHARACTER	4
#define WHITE_SPACE	5

typedef char	Bool;
#define True	1
#define False	0

typedef int	State;
#define	Code	0
#define Comment	1
#define Quiescent	2

#define FNULL	( (FILE *) 0)
#define CNULL	( (char *) 0)

char objc_comm = 'N';

	id myobj;

 {
	register Token 	input;
	register State	statevar = Quiescent, laststate = Quiescent;
	int	filecount = 0;
	long	cod_linect, com_linect, blnk_linect, comment_ct;
	long	tot_cdline, tot_cmline, tot_bkline, tot_comment;
	long	grand_tot_cdline, grand_tot_cmline, grand_tot_bkline, grand_tot_comment;
	Bool	following_com = False;
	FILE	*fp;

  const char *file, *directory;
  const char *const *filenames;
  static const char
  *const wordTypes[] = {EXTENSION_LIST, NULL};
  char fullPathName[MAXPATHLEN];
  id openPanel = [OpenPanel new];
 	
  [openPanel allowMultipleFiles:NO];
  if ([openPanel runModalForTypes:wordTypes])
  {
	filenames = [openPanel filenames];
	directory = [openPanel directory];
	    file = *(filenames++);
	    strcpy(fullPathName, directory);
	    strcat(fullPathName, "/");
	    strcat(fullPathName, file);
	    strcpy(filename, file);	
	     } 					 		

	if( strncmp(fullPathName, "\000", 1) == 0 || 
(fp = fopen(fullPathName, "r")) == NULL )
    	{
    	 return NO;
   	 	}

	tot_cdline = tot_cmline = tot_bkline = tot_comment = 0;
	grand_tot_cdline = grand_tot_cmline = grand_tot_bkline = grand_tot_comment = 0;

	{
		cod_linect = com_linect = blnk_linect = comment_ct = 0;
		filecount++;

      	        while (!feof(fp)) {
		{


{
	/* return Token  for char type, taking into account comment delims */
	/* ignores spaces and tabs */

	register int	c;
	register Token 	retval;
	static int	buf;
	static Bool	inbuf = False;
	do
	{
		if ( inbuf )
		{
			c = buf;
			inbuf = False;
		}
		else
			c = getc(fp);
		
		switch ( c )
		{
		case EOF:
			retval = STOP_INPUT;
			break;
		case '\n':
			retval = NEWLINE;
			break; 
		case '/':
			buf = getc(fp);
			if ( buf == '*' )
				retval = START_COMMENT;
			else if (buf == '/' ) {
				objc_comm = 'Y';
				retval = END_COMMENT; }
			else
			{
				inbuf = True;
				retval = MISC_CHARACTER;
			}
			break;
		case '*':
			buf = getc(fp);
			if ( buf == '/' )
				retval = END_COMMENT;
			else
			{
				inbuf = True;
				retval = MISC_CHARACTER;
			}
			break;
		case ' ':
		case '\t':
			retval = WHITE_SPACE;
			break;
		default:
			retval = MISC_CHARACTER;
		}
	}
	while ( retval == WHITE_SPACE );

 			input = retval;
			switch ( input )
			{
			case NEWLINE:
				if ( statevar == Code && objc_comm == 'N')
					cod_linect++;
				else if ( statevar == Comment || objc_comm == 'Y')
					{com_linect++;
					objc_comm = 'N';}
				/* state is quiescent */
				else if ( laststate == Comment )
				{
					/* if is supposed to catch cases where a comment
					 * follows a line of code
					 */
					if ( following_com ) 
						cod_linect++;
					else
						com_linect++;
				}
				else
					blnk_linect++;
				if ( statevar != Comment )
				{
					laststate = Quiescent;
					statevar = Quiescent;
				}
				following_com = False;
				break;
			case START_COMMENT:
				laststate = statevar;
				statevar = Comment;
				break;
			case END_COMMENT:
				comment_ct++;
					/* if true, is a comment on same line as code */
				if ( laststate == Code )
					following_com = True;

				laststate = Comment;
				statevar = Quiescent;
				break;
			case MISC_CHARACTER:
				if ( statevar == Quiescent )
				{
					laststate = statevar;
					statevar = Code;
				}
				break;
			default:
			lines = cod_linect;
			blanks = blnk_linect;
			comments = com_linect;
			}
		}
		tot_cdline += lines;
		tot_cdline += cod_linect;
		tot_cmline += com_linect;
		tot_bkline += blnk_linect;
		tot_comment += comment_ct;

		grand_tot_cdline += tot_cdline;
		grand_tot_cmline += tot_cmline;
		grand_tot_bkline += tot_bkline;
		grand_tot_comment += tot_comment;
	}

}
}
}
	myobj = [[ConvertObject alloc] init];

	[fileOutlet setStringValue:filename];
	[linesOutlet setFloatValue:lines];
	[blnkOutlet setFloatValue:blanks];
	[comOutlet setFloatValue:comments];
	
	return self;
}

@end
